#-------------------------------------------------------------------------------
# Name:        module1
# Purpose:
#
# Author:      Federico
#
# Created:     22/08/2011
# Copyright:   (c) Federico 2011
# Licence:     <your licence>
#-------------------------------------------------------------------------------
#!/usr/bin/env python

import ply.lex as lexer

palabras_reservadas =  ['ABSTRACT','AS','BASE','BOOL','BREAK','BYTE','CASE','CATCH','CHAR','CHECKED','CLASS','CONST','CONTINUE','DECIMAL','DEFAULT','DELEGATE','DO','DOUBLE','ELSE',
                       'ENUM','EVENT','EXPLICIT','EXTERN','FALSE','FINALLY','FIXED','FLOAT','FOR','FOREACH','GOTO','IF','IMPLICIT','IN','INT','INTERFACE','INTERNAL','IS','LOCK','LONG',
                       'NAMESPACE','NEW','NULL','OBJECT','OPERATOR','OUT','OVERRIDE','PARAMS','PRIVATE','PROTECTED','PUBLIC','READONLY','REF','RETURN','SBYTE','SEALED','SHORT','SIZEOF',
                       'STACKALLOC','STATIC','STRING','STRUCT','SWITCH','THIS','THROW','TRUE','TRY','TYPEOF','UINT','ULONG','UNCHECKED','UNSAFE','USHORT','USING','VIRTUAL','VOID','VOLATILE',
                       'WHILE','PARTIAL','YIELD','ALIAS','WHERE','GET','SET','BLOCK','ADD','REMOVE']

palabras_reservadas_dict = dict([(x.lower(),x)for x in palabras_reservadas])

operadores_puntuacion = ["ABRE_LLAVE","CIERRA_LLAVE","ABRE_CORCHETE","CIERRA_CORCHETE","ABRE_PARENTESIS","CIERRA_PARENTESIS","PUNTO","COMA","DOS_PUNTOS","PUNTO_COMA","SUMA","RESTA",
                         "MULTIPLICACION","DIVISION","RESTO","BOOLEANO","OR","OR_EXCLUSIVO","NOT","NOT_BIT","IGUAL","MENOR","MAYOR","CONDICIONAL","DOBLE_CONDICIONAL","OPERADOR_NAMESPACE",
                         "INCREMENTAL","DECREMENTAL","CONDICIONAL_AND","CONDICIONAL_OR","FLECHA","DOBLE_IGUAL","DISTINTO","MENOR_IGUAL","MAYOR_IGUAL","SUMA_ABREVIADA",
                         "RESTA_ABREVIADA","MULTIPLICACION_ABREVIADA","DIVISION_ABREVIADA","RESTO_ABREVIADO","BOOLEANO_ABREVIADO","OR_ABREVIADO","OR_EXCLUSIVO_ABREVIADO",
                         "SHIFT_IZQUIERDA","SHIFT_IZQUIERDA_ABREVIADO","SHIFT_DERECHA","SHIFT_DERECHA_ABREVIADO"]

operadores_puntuacion_dict = dict([(x,x)for x in operadores_puntuacion])

tokens = ("DIGITO","EXPONENCIAL","ID","CARACTER","CADENA_CARACTERES") + tuple(palabras_reservadas_dict.values()) + tuple(operadores_puntuacion_dict.values())

'----------------------FUNCIONES_VARIAS-------------------------------------'

def t_DIGITO(t):
    r'\d+'
    t.value=int(t.value)
    t.type=palabras_reservadas_dict.get(t.value,'DIGITO')
    return t

def t_EXPONENCIAL(t):
    r'(e|E)(\+|-)*\d+'
    t.type=palabras_reservadas_dict.get(t.value,'EXPONENCIAL')
    return t

def t_ID(t):
    r'[a-zA-Z_]\w*'
    t.type=palabras_reservadas_dict.get(t.value,'ID')
    return t

def t_CARACTER(t):
    r'(\'[a-zA-Z]\')|(\"[a-zA-Z]\")'
    t.type=palabras_reservadas_dict.get(t.value,'CARACTER')
    return t

def t_CADENA_CARACTERES(t):
    r'(\'[a-zA-Z]+\')|(\"[a-zA-Z]+\")'
    t.type=palabras_reservadas_dict.get(t.value,'CADENA_CARACTERES')
    return t

#Ignorar espacios en blanco
t_ignore=' \t'

#Descarta comentarios
def t_coment(t):
    r'(\/\*.*\*\/) | (//.*)'

'----------------------OPERADORES_PUNTUACION-------------------------------------'

t_ABRE_LLAVE=r'\{'
t_CIERRA_LLAVE=r'\}'
t_ABRE_CORCHETE=r'\['
t_CIERRA_CORCHETE=r'\]'
t_ABRE_PARENTESIS=r'\('
t_CIERRA_PARENTESIS=r'\)'
t_PUNTO=r'\.'
t_COMA=r'\,'
t_DOS_PUNTOS=r'\:'
t_PUNTO_COMA=r'\;'
t_SUMA=r'\+'
t_RESTA=r'\-'
t_MULTIPLICACION=r'\*'
t_DIVISION=r'\/'
t_RESTO=r'\%'
t_BOOLEANO=r'\&'
t_OR=r'\|'
t_OR_EXCLUSIVO=r'\^'
t_NOT=r'\!'
t_NOT_BIT=r'\~'
t_IGUAL=r'\='
t_MENOR=r'\<'
t_MAYOR=r'\>'
t_CONDICIONAL=r'\?'
t_DOBLE_CONDICIONAL=r'\?\?'
t_OPERADOR_NAMESPACE=r'\:\:'
t_INCREMENTAL=r'\+\+'
t_DECREMENTAL=r'\-\-'
t_CONDICIONAL_AND=r'\&\&'
t_CONDICIONAL_OR=r'\|\|'
t_FLECHA=r'\-\>'
t_DOBLE_IGUAL=r'\=\='
t_DISTINTO=r'\!\='
t_MENOR_IGUAL=r'\<\='
t_MAYOR_IGUAL=r'\>\='
t_SUMA_ABREVIADA=r'\+\='
t_RESTA_ABREVIADA=r'\-\='
t_MULTIPLICACION_ABREVIADA=r'\*\='
t_DIVISION_ABREVIADA=r'\/\='
t_RESTO_ABREVIADO=r'\%\='
t_BOOLEANO_ABREVIADO=r'\&\='
t_OR_ABREVIADO=r'\|\='
t_OR_EXCLUSIVO_ABREVIADO=r'\^\='
t_SHIFT_IZQUIERDA=r'\<\<'
t_SHIFT_IZQUIERDA_ABREVIADO=r'\<\<\='
t_SHIFT_DERECHA=r'\>\>'
t_SHIFT_DERECHA_ABREVIADO=r'\>\>\='

#Contar nuevas lineas
def t_newline(t):
    r'\n+'
    t.lexer.lineno += len(t.value)

#Control de Errores
def t_error(t):
    print "\nlex: Error lexico en linea %d, token='%s'\n" % (t.lineno, t.value[0])
    t.lexer.skip(1)

lexer=lexer.lex()

if __name__=='__main__':
    entrada=''' "a" 'a' "abc" 'abc' e-5 E+10 e1 E10 if algo= b then a=(c,b) 156 354 @
                hola IF abc namespace abstract@
                //hola
                *hola*/'''
    lexer.input(entrada)
    while True:
        tok=lexer.token()
        if not tok:break
        print tok
